package com.df.twod_sync_bakend.game.scripts;

import com.alibaba.fastjson2.JSON;
import com.df.twod_sync_bakend.game.GameRoom;
import com.df.twod_sync_bakend.game.IScript;
import com.df.twod_sync_bakend.game.entity.InputCommand;
import com.df.twod_sync_bakend.game.msgs.Msg_Login_Req;
import com.df.twod_sync_bakend.game.msgs.Msg_Move_Req;
import com.df.twod_sync_bakend.game.msgs.Msg_Move_Resp;
import com.df.twod_sync_bakend.model.Player;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

@Slf4j
@Component
public class MoveScript implements IScript<Msg_Move_Req> {
    @Override
    public String getType() {
        return "Move";
    }

    @Override
    public Msg_Move_Req unserialize(String msgStr) {
        if(msgStr!=null){
            return JSON.parseObject(msgStr, Msg_Move_Req.class);
        }
        return null;
    }

    // 游戏配置
    private static final float INPUT_VALIDATION_THRESHOLD = 1.5f;

    @Override
    public void handle(WebSocketSession session, Msg_Move_Req req, GameRoom room) {
        Object o = session.getAttributes().get("uid");
        if(o == null){
            return;
        }
        String uid = o.toString();

        try {
            // 验证请求
            if (!validateMoveRequest(req)) {
                room.sendFailMsg(uid, getType(), "Invalid move request", 400);
                return;
            }

            // 处理移动输入
            Player player = room.getPlayers().get(uid);
            if (player == null) {
                room.sendFailMsg(uid, getType(), "Player not found", 404);
                return;
            }

            // 添加输入到队列
            room.addMoveInputs(uid, req.getInputs());

            // 发送输入确认
            sendInputConfirmation(uid, req, player, room);

        } catch (Exception e) {
            log.error("处理移动请求失败 uid: {}", uid, e);
            room.sendFailMsg(uid, getType(), "Server error", 500);
        }
    }

    // 验证移动请求
    private boolean validateMoveRequest(Msg_Move_Req req) {
        if (req == null) {
            return false;
        }

        // 检查时间戳合理性
        long currentTime = System.currentTimeMillis();
        if (req.getClientTime() != null) {
            long timeDiff = Math.abs(currentTime - req.getClientTime());
            if (timeDiff > 5000) { // 5秒时间差
                log.warn("时间戳异常: clientTime={}, serverTime={}", req.getClientTime(), currentTime);
                return false;
            }
        }

        // 检查输入数据
        if (req.getInputs() != null && !req.getInputs().isEmpty()) {
            for (InputCommand input : req.getInputs()) {
                if (!validateInputCommand(input)) {
                    return false;
                }
            }
        } else {
//            // 兼容单个移动命令
//            if (!validateSingleMove(req)) {
//                return false;
//            }
        }

        return true;
    }
    // 验证输入命令
    private boolean validateInputCommand(InputCommand input) {
        if (input == null) {
            return false;
        }

        // 检查序列号
        if (input.getSequence() == null || input.getSequence() < 0) {
            return false;
        }

        // 检查方向向量
        if (input.getDirectionX() != null && input.getDirectionY() != null) {
            float magnitude = (float) Math.sqrt(
                    input.getDirectionX() * input.getDirectionX() +
                            input.getDirectionY() * input.getDirectionY()
            );

            if (magnitude > INPUT_VALIDATION_THRESHOLD) {
                log.warn("方向向量异常: magnitude={}", magnitude);
                return false;
            }
        }

        // 检查时间戳
        if (input.getTimestamp() != null) {
            long currentTime = System.currentTimeMillis();
            long timeDiff = Math.abs(currentTime - input.getTimestamp());
            if (timeDiff > 10000) { // 10秒时间差
                log.warn("输入时间戳异常: inputTime={}, serverTime={}", input.getTimestamp(), currentTime);
                return false;
            }
        }

        return true;
    }

    // 发送输入确认
    private void sendInputConfirmation(String uid, Msg_Move_Req req, Player player, GameRoom room) {
        Msg_Move_Resp response = new Msg_Move_Resp()
                .setUid(uid)
                .setClientTime(req.getClientTime())
                .setSequence(req.getSequence())
                .setServerTime(System.currentTimeMillis())
                .setLastProcessedSequence(player.getLastProcessedSequence());

        // 设置当前位置和速度
        response.setPosX(player.getPosX());
        response.setPosY(player.getPosY());
        response.setVelocityX(player.getVelocityX());
        response.setVelocityY(player.getVelocityY());

        // 只发送给当前玩家（输入确认）
        room.sendMsg(uid, "MoveConfirm", response);
    }
}
